package com.ltcode.auth.domain.repository;

import com.ltcode.auth.domain.model.AuthToken;

import java.util.List;
import java.util.Optional;

/**
 * 认证令牌仓储接口
 * 
 * @author ltcode
 * @since 2024-01-01
 */
public interface AuthTokenRepository {

    /**
     * 保存令牌
     * 
     * @param token 令牌信息
     * @return 保存后的令牌信息
     */
    AuthToken save(AuthToken token);

    /**
     * 根据令牌ID查询令牌
     * 
     * @param tokenId 令牌ID
     * @return 令牌信息
     */
    Optional<AuthToken> findByTokenId(String tokenId);

    /**
     * 根据用户ID查询所有有效令牌
     * 
     * @param userId 用户ID
     * @return 令牌列表
     */
    List<AuthToken> findActiveTokensByUserId(Long userId);

    /**
     * 根据用户ID和令牌类型查询令牌
     * 
     * @param userId 用户ID
     * @param tokenType 令牌类型
     * @return 令牌列表
     */
    List<AuthToken> findByUserIdAndType(Long userId, AuthToken.TokenType tokenType);

    /**
     * 删除令牌
     * 
     * @param tokenId 令牌ID
     */
    void deleteByTokenId(String tokenId);

    /**
     * 撤销用户的所有令牌
     * 
     * @param userId 用户ID
     */
    void revokeAllTokensByUserId(Long userId);

    /**
     * 撤销指定类型的令牌
     * 
     * @param userId 用户ID
     * @param tokenType 令牌类型
     */
    void revokeTokensByUserIdAndType(Long userId, AuthToken.TokenType tokenType);

    /**
     * 更新令牌状态
     * 
     * @param tokenId 令牌ID
     * @param status 新状态
     */
    void updateTokenStatus(String tokenId, AuthToken.TokenStatus status);

    /**
     * 刷新令牌过期时间
     * 
     * @param tokenId 令牌ID
     * @param expireMinutes 过期分钟数
     */
    void refreshTokenExpireTime(String tokenId, long expireMinutes);

    /**
     * 清理过期令牌
     */
    void cleanExpiredTokens();

    /**
     * 检查令牌是否存在
     * 
     * @param tokenId 令牌ID
     * @return 是否存在
     */
    boolean existsByTokenId(String tokenId);

    /**
     * 统计用户的活跃令牌数量
     * 
     * @param userId 用户ID
     * @return 活跃令牌数量
     */
    long countActiveTokensByUserId(Long userId);

    /**
     * 获取用户最近的登录令牌
     * 
     * @param userId 用户ID
     * @return 最近的访问令牌
     */
    Optional<AuthToken> findLatestAccessTokenByUserId(Long userId);
}
